#include "CDateTime.h"

CDateTime::CDateTime()
{
    Initialize();
}
CDateTime::CDateTime(int year, int month, int day, int hour, int minute, int second)
{
    m_dateTime.tm_year = year - 1900;
    m_dateTime.tm_mon = month - 1;
    m_dateTime.tm_mday = day;
    m_dateTime.tm_hour = hour;
    m_dateTime.tm_min = minute;
    m_dateTime.tm_sec = second;
}
void CDateTime::InitTime(struct tm *date_time, time_t *time_now)
{
#if defined _WIN32 || defined _WIN64
    localtime_s(date_time, time_now);
#else
    localtime_r(time_now, date_time);
#endif
}
void CDateTime::Initialize()
{
    gettimeofday(&m_tval, NULL);
    m_now = (time_t)m_tval.tv_sec;
    m_ms = (int)m_tval.tv_usec / 1000;
    m_us = (int)m_tval.tv_usec % 1000;
    InitTime(&m_dateTime, &m_now);
}
void CDateTime::SetDateTimeByString(const std::string &datetimeStr)
{
    std::size_t strlength = datetimeStr.size();
    if (strlength < 4)
        return;
    m_dateTime.tm_year = strlength >= 4 ? std::stoi(datetimeStr.substr(0, 4)) - 1900 : 0000;
    m_dateTime.tm_mon = strlength >= 6 ? std::stoi(datetimeStr.substr(4, 2)) - 1 : 00;
    m_dateTime.tm_mday = strlength >= 8 ? std::stoi(datetimeStr.substr(6, 2)) : 00;
    m_dateTime.tm_hour = strlength >= 10 ? std::stoi(datetimeStr.substr(8, 2)) : 00;
    m_dateTime.tm_min = strlength >= 12 ? std::stoi(datetimeStr.substr(10, 2)) : 00;
    m_dateTime.tm_sec = strlength >= 14 ? std::stoi(datetimeStr.substr(12, 2)) : 00;
    m_now = std::mktime(&m_dateTime);
}
CDateTime &CDateTime::InitTimeStamp(time_t timestamp)
{
    InitTime(&m_dateTime, &timestamp);
    return *this;
}
CDateTime &CDateTime::AddDay(int day)
{
    m_dateTime.tm_mday += day;
    std::mktime(&m_dateTime);
    return *this;
}
CDateTime &CDateTime::AddMonth(int month)
{
    m_dateTime.tm_mon += month;
    std::mktime(&m_dateTime);
    return *this;
}
CDateTime &CDateTime::AddYear(int year)
{
    m_dateTime.tm_year += year;
    std::mktime(&m_dateTime);
    return *this;
}
CDateTime &CDateTime::SubtractDay(int day)
{
    m_dateTime.tm_mday -= day;
    std::mktime(&m_dateTime);
    return *this;
}
CDateTime &CDateTime::SubtractMonth(int month)
{
    m_dateTime.tm_mon -= month;
    std::mktime(&m_dateTime);
    return *this;
}
CDateTime &CDateTime::SubtractYear(int year)
{
    m_dateTime.tm_year -= year;
    std::mktime(&m_dateTime);
    return *this;
}
bool CDateTime::operator>(const CDateTime &date_time) const
{
    return false;
}
bool CDateTime::operator<(const CDateTime &date_time) const
{
    return false;
}
bool CDateTime::operator==(const CDateTime &date_time) const
{
    return false;
}
bool CDateTime::operator!=(const CDateTime &date_time) const
{
    return false;
}
int CDateTime::GetYear() const
{
    return m_dateTime.tm_year + 1900;
}
int CDateTime::GetMonth() const
{
    return m_dateTime.tm_mon + 1;
}
int CDateTime::GetDay() const
{
    return m_dateTime.tm_mday;
}
int CDateTime::GetHour() const
{
    return m_dateTime.tm_hour;
}
int CDateTime::GetMinute() const
{
    return m_dateTime.tm_min;
}
int CDateTime::GetSecond() const
{
    return m_dateTime.tm_sec;
}
int CDateTime::FormatYYYYMMDD()
{
    std::string buffer = Format("%4d%02d%02d");
    return std::stoi(buffer);
}
std::string CDateTime::FormatYYYYMMDDHHmmss()
{
    std::string buffer = Format("%04d%02d%02d%02d%02d%02d");
    return buffer;
}
std::string CDateTime::FormatYYYYMMDDHHmmssSSS()
{
    std::string buffer = Format("%04d%02d%02d%02d%02d%02d%03d");
    return buffer;
}
std::string CDateTime::ToString() const
{
    char buffer[64];
    std::strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S", &m_dateTime);
    return std::string(buffer);
}
std::string CDateTime::Format(const char *formater)
{
    char buffer[256];
    // std::strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S", &m_dateTime);
    snprintf(buffer, sizeof(buffer), formater,
             m_dateTime.tm_year + 1900, m_dateTime.tm_mon + 1, m_dateTime.tm_mday,
             m_dateTime.tm_hour, m_dateTime.tm_min, m_dateTime.tm_sec, m_ms, m_us);
    return std::string(buffer);
}
